home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / MSJV7_2B.ARJ / DIALOG.C < prev    next >
C/C++ Source or Header  |  1992-03-01  |  40KB  |  1,147 lines

  1. /*
  2.  * dialog.c - Handles the Windows 3.1 common dialogs.
  3.  *
  4.  * Created by Microsoft Corporation.
  5.  * (c) Copyright Microsoft Corp. 1990 - 1992  All Rights Reserved
  6.  */
  7.  
  8. //*** INCLUDES ****
  9.  
  10. #include <windows.h>                   //* WINDOWS
  11. #include <ole.h>                       //* OLE
  12.  
  13. #include "global.h"                    //* global 
  14. #include "demorc.h"                       //* String table constants 
  15. #include "register.h"                    //* Class registration library
  16. #include "utility.h"
  17. #include "dialog.h"
  18. #include "object.h"
  19.  
  20. //*** GLOBALS ***
  21.                                        //* strings used with commdlg
  22. char        szDefExtension[CBMESSAGEMAX];
  23. char        szFilterSpec[CBFILTERMAX];
  24. char        szInsertFilter[CBFILTERMAX];
  25. char        szLastDir[CBPATHMAX];
  26. OPENFILENAME OFN;
  27. HWND        hwndProp = NULL;
  28. HWND        hRetry;
  29.  
  30. /***************************************************************************
  31.  * OfnInit() 
  32.  * Initializes the standard file dialog OFN structure.
  33.  **************************************************************************/
  34.  
  35. void FAR OfnInit(                      //* ENTRY:
  36.    HANDLE         hInst                //* instance handle
  37. ){                                     //* LOCAL:
  38.    LPSTR          lpstr;               //* string pointer
  39.  
  40.    LoadString(hInst, IDS_FILTER, szFilterSpec, CBMESSAGEMAX);
  41.    LoadString(hInst, IDS_EXTENSION, szDefExtension, CBMESSAGEMAX);
  42.  
  43.    OFN.lStructSize    = sizeof(OPENFILENAME);
  44.    OFN.hInstance      = hInst;
  45.    OFN.nMaxCustFilter = CBFILTERMAX;
  46.    OFN.nMaxFile       = CBPATHMAX;
  47.    OFN.lCustData      = NULL;
  48.    OFN.lpfnHook       = NULL;
  49.    OFN.lpTemplateName = NULL;
  50.    OFN.lpstrFileTitle = NULL;
  51.                                        //* Construct the filter string 
  52.                                        //* for the Open and Save dialogs 
  53.    lpstr = (LPSTR)szFilterSpec;
  54.    lstrcat(lpstr, " (*.");
  55.    lstrcat(lpstr, szDefExtension);
  56.    lstrcat(lpstr, ")");
  57.    lpstr += lstrlen(lpstr) + 1;
  58.  
  59.    lstrcpy(lpstr, "*.");
  60.    lstrcat(lpstr, szDefExtension);
  61.    lpstr += lstrlen(lpstr) + 1;
  62.    *lpstr = 0;
  63.  
  64.    RegMakeFilterSpec(NULL, NULL, (LPSTR)szInsertFilter);
  65.  
  66. }
  67.  
  68. /***************************************************************************
  69.  * OfnGetName() 
  70.  *
  71.  * Calls the standard file dialogs to get a file name
  72.  **************************************************************************/
  73.  
  74. BOOL FAR OfnGetName(                   //* ENTRY:
  75.    HWND           hwnd,                //* parent window handle
  76.    LPSTR          szFileName,          //* File name
  77.    WORD           msg                  //* operation
  78. ){                                     //* LOCAL:
  79.    BOOL           frc;                 //* return flag
  80.    char           szCaption[CBMESSAGEMAX];//* dialog caption
  81.  
  82.    OFN.hwndOwner       = hwnd;               //* window
  83.    OFN.nFilterIndex    = 1;
  84.    OFN.lpstrInitialDir = (LPSTR)szLastDir;
  85.    OFN.Flags           = OFN_HIDEREADONLY;
  86.  
  87.    switch (msg)                        //* message
  88.    {                                   
  89.       case IDM_OPEN:                   //* open file
  90.          Normalize(szFileName);
  91.          OFN.lpstrDefExt = (LPSTR)szDefExtension;
  92.          OFN.lpstrFile   = (LPSTR)szFileName;
  93.          OFN.lpstrFilter = (LPSTR)szFilterSpec;
  94.          LoadString(hInst, IDS_OPENFILE, szCaption, CBMESSAGEMAX);
  95.          OFN.lpstrTitle  = (LPSTR)szCaption;
  96.          OFN.Flags       |= OFN_FILEMUSTEXIST;
  97.          return GetOpenFileName((LPOPENFILENAME)&OFN);
  98.          break;
  99.  
  100.       case IDM_SAVEAS:                 //* save as file
  101.          Normalize(szFileName);
  102.          OFN.lpstrDefExt = (LPSTR)szDefExtension;
  103.          OFN.lpstrFile   = (LPSTR)szFileName;
  104.          OFN.lpstrFilter = (LPSTR)szFilterSpec;
  105.          LoadString(hInst, IDS_SAVEFILE, szCaption, CBMESSAGEMAX);
  106.          OFN.lpstrTitle  = (LPSTR)szCaption;
  107.          OFN.Flags       |= OFN_PATHMUSTEXIST;
  108.          return GetSaveFileName((LPOPENFILENAME)&OFN);
  109.          break;
  110.                                        
  111.       case IDM_INSERTFILE:             //* insert file
  112.          OFN.lpstrDefExt = NULL;
  113.          OFN.lpstrFile   = (LPSTR)szFileName;
  114.          OFN.lpstrFilter = (LPSTR)szInsertFilter;
  115.          LoadString(hInst, IDS_INSERTFILE, szCaption, CBMESSAGEMAX);
  116.          OFN.lpstrTitle  = (LPSTR)szCaption;
  117.          OFN.Flags      |= OFN_FILEMUSTEXIST;
  118.          frc             = GetOpenFileName((LPOPENFILENAME)&OFN);
  119.          AddExtension(&OFN);
  120.          return frc;
  121.          break;
  122.  
  123.       default:                         //* default
  124.          break;
  125.    }
  126.  
  127. }
  128.  
  129. /***************************************************************************
  130.  * OfnGetNewLinkName() - Sets up the "Change Link..." dialog box
  131.  *
  132.  * returns LPSTR - fully qualified filename  
  133.  **************************************************************************/
  134.  
  135. LPSTR FAR OfnGetNewLinkName(           //* ENTRY:
  136.    HWND           hwnd,                //* calling window or dialog
  137.    LPSTR          lpstrData            //* link data
  138. ){                                     //* LOCAL:
  139.    LPSTR          lpReturn = NULL;     //* return string
  140.    LPSTR          lpstrFile = NULL;    //* non-qualified file name   
  141.    LPSTR          lpstrPath = NULL;    //* pathname
  142.    LPSTR          lpstrTemp = NULL;    //* work string
  143.    char           szDocFile[CBPATHMAX];//* document name
  144.    char           szDocPath[CBPATHMAX];//* document path name
  145.    char           szServerFilter[CBPATHMAX]; 
  146.    char           szCaption[CBMESSAGEMAX];
  147.  
  148.                                        //* Figure out the link's path 
  149.                                        //* name and file name 
  150.    lpstrTemp = lpstrData;
  151.    while (*lpstrTemp++);
  152.    lpstrPath = lpstrFile = lpstrTemp;
  153.  
  154.    while (*(lpstrTemp = AnsiNext(lpstrTemp)))
  155.       if (*lpstrTemp == '\\')
  156.          lpstrFile = lpstrTemp + 1;
  157.                                         //* Copy the document name
  158.    lstrcpy(szDocFile, lpstrFile);
  159.    *(lpstrFile - 1) = 0;
  160.                                           //* Copy the path name 
  161.    lstrcpy(szDocPath, ((lpstrPath != lpstrFile) ? lpstrPath : ""));
  162.    if (lpstrPath != lpstrFile)           //* Restore the backslash
  163.       *(lpstrFile - 1) = '\\';
  164.    while (*lpstrFile != '.' && *lpstrFile)//* Get the extension 
  165.     lpstrFile++;
  166.                                           //* Make a filter that respects 
  167.                                           //* the link's class name 
  168.    OFN.hwndOwner       = hwnd;
  169.    OFN.nFilterIndex    = RegMakeFilterSpec(lpstrData, lpstrFile, szServerFilter);
  170.    OFN.lpstrDefExt     = NULL;
  171.    OFN.lpstrFile       = (LPSTR)szDocFile;
  172.    OFN.lpstrFilter     = (LPSTR)szServerFilter;
  173.    OFN.lpstrInitialDir = (LPSTR)szDocPath;
  174.    LoadString(hInst, IDS_CHANGELINK, szCaption, CBMESSAGEMAX);
  175.    OFN.lpstrTitle     = (LPSTR)szCaption;
  176.    OFN.lpstrCustomFilter = NULL;
  177.    OFN.Flags          = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
  178.  
  179.                                            //* If we get a file... */
  180.    if (GetOpenFileName((LPOPENFILENAME)&OFN)) 
  181.    {
  182.       if (!(lpReturn = GlobalLock(GlobalAlloc(LHND, CBPATHMAX))))
  183.          goto Error;
  184.  
  185.       AddExtension(&OFN);
  186.       lstrcpy(lpReturn, szDocFile);
  187.  
  188.       OFN.lpstrInitialDir = (LPSTR)szLastDir;
  189.    }
  190.  
  191.    return lpReturn;                    //* SUCCESS return
  192.  
  193. Error:                                 //* ERROR Tag
  194.  
  195.    return NULL;                        //* ERROR return
  196.    
  197. }
  198.  
  199. /***************************************************************************
  200.  * Normalize()  
  201.  * Removes the path specification from the file name.
  202.  *
  203.  * Note:  It isn't possible to get "<drive>:<filename>" as input because
  204.  *        the path received will always be fully qualified.
  205.  **************************************************************************/
  206.  
  207. void Normalize(                        //* ENTRY:
  208.    LPSTR          lpstrFile            //* file name
  209. ){                                     //* LOCAL:
  210.    LPSTR          lpstrBackslash = NULL;//* back slash
  211.    LPSTR          lpstrTemp = lpstrFile;//* file name
  212.  
  213.    while (*lpstrTemp) 
  214.    {
  215.       if (*lpstrTemp == '\\')
  216.          lpstrBackslash = lpstrTemp;
  217.  
  218.       lpstrTemp = AnsiNext(lpstrTemp);
  219.    }
  220.    if (lpstrBackslash)
  221.       lstrcpy(lpstrFile, lpstrBackslash + 1);
  222.  
  223. }
  224.  
  225. /***************************************************************************
  226.  * AddExtension() 
  227.  *
  228.  * Adds the extension corresponding to the filter dropdown.
  229.  **************************************************************************/
  230.  
  231. void AddExtension(                     //* ENTRY:
  232.    LPOPENFILENAME lpOFN                //* open file structure
  233. ){
  234.  
  235.    if (lpOFN->nFileExtension == (WORD)lstrlen(lpOFN->lpstrFile) 
  236.          && lpOFN->nFilterIndex) 
  237.    {
  238.       LPSTR   lpstrFilter = (LPSTR)lpOFN->lpstrFilter;
  239.  
  240.       while (*lpstrFilter && --lpOFN->nFilterIndex) 
  241.       {
  242.          while (*lpstrFilter++) ;
  243.          while (*lpstrFilter++) ;
  244.       }
  245.                                        //* If we got to the filter, 
  246.       if (*lpstrFilter)                //* retrieve the extension 
  247.       {
  248.          while (*lpstrFilter++) ;
  249.          lpstrFilter++;
  250.                                        //* Copy the extension 
  251.          if (lpstrFilter[1] != '*')
  252.             lstrcat(lpOFN->lpstrFile, lpstrFilter);
  253.       }
  254.    }
  255.  
  256. }
  257. /****************************************************************************
  258.  *  fnInsertNew()
  259.  *
  260.  *  Dialog procedure for the Insert New dialog.
  261.  *
  262.  *  Returns int - TRUE if message processed, FALSE otherwise
  263.  ***************************************************************************/
  264.  
  265. BOOL FAR PASCAL fnInsertNew(           //* ENTRY:
  266.    HWND           hDlg,                //* standard dialog box paramters
  267.    unsigned       msg, 
  268.    WORD           wParam, 
  269.    LONG           lParam               //* (LPSTR) class name
  270. ){                                     //* LOCAL:
  271.    HWND           hwndList;            //* handle to listbox 
  272.    static LPSTR   lpClassName;         //* classname for return value
  273.    
  274.    hwndList = GetDlgItem(hDlg, IDD_LISTBOX);
  275.  
  276.    switch (msg) 
  277.    {
  278.       case WM_INITDIALOG:
  279.          if (!RegGetClassNames(hwndList))
  280.             EndDialog(hDlg, IDCANCEL);
  281.  
  282.          lpClassName = (LPSTR)lParam;
  283.          SetFocus(hwndList);
  284.          SendMessage(hwndList, LB_SETCURSEL, 0, 0L);
  285.          return (FALSE);
  286.  
  287.       case WM_COMMAND:
  288.          switch (wParam) 
  289.          {
  290.             case IDD_LISTBOX:
  291.                if (HIWORD(lParam) != LBN_DBLCLK)
  292.                break;
  293.  
  294.             case IDOK:
  295.                if (!RegCopyClassName(hwndList, lpClassName))
  296.                   wParam = IDCANCEL;
  297.  
  298.             case IDCANCEL:
  299.                EndDialog(hDlg, wParam);
  300.                break;
  301.          }
  302.          break;
  303.    }
  304.    return FALSE;              
  305.  
  306. }
  307.  
  308. /***************************************************************************
  309.  * LinkProperties();
  310.  *
  311.  * Manage the link properties dialog box.
  312.  **************************************************************************/
  313.  
  314. void FAR LinkProperties()             
  315. {                                      //* LOCAL
  316.    FARPROC        lpfnProperties;      //* Properties
  317.  
  318.    lpfnProperties   = MakeProcInstance(fnProperties, hInst);
  319.    DialogBox (
  320.       hInst, 
  321.       MAKEINTRESOURCE(DTPROP), 
  322.       hwndFrame, 
  323.       lpfnProperties 
  324.    );
  325.    FreeProcInstance(lpfnProperties);
  326.  
  327. }
  328.  
  329. /***************************************************************************
  330.  * fnProperties()
  331.  *
  332.  * Dialog procedure for link properties. The Links dialog allows the user to
  333.  * change the link options, edit/play the object, cancel the link as 
  334.  * well change links.
  335.  *
  336.  *    returns BOOL - TRUE if processed, FALSE otherwise
  337.  **************************************************************************/
  338.  
  339. BOOL FAR PASCAL fnProperties(          //* ENTRY:
  340.    HWND           hDlg,                //* standard dialog box parameters
  341.    unsigned       msg,                       
  342.    WORD           wParam, 
  343.    LONG           lParam               //* (HWND) child window with focus
  344. ){                                     //* LOCAL:
  345.   static APPITEMPTR *pLinks;           //* pointer to links (associated windows)
  346.   static int      nLinks;              //* number of links
  347.   static HWND     hwndList;            //* handle to listbox window 
  348.   static BOOL     fTry;
  349.  
  350.    switch (msg) 
  351.    {
  352.        case WM_INITDIALOG: 
  353.          hwndProp = hDlg;
  354.          hwndList = GetDlgItem(hDlg, IDD_LINKNAME);
  355.          if (!(InitLinkDlg(hDlg, &nLinks, hwndList, &pLinks)))
  356.             EndDialog(hDlg, TRUE);
  357.          UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  358.          break;
  359.  
  360.       case WM_COMMAND: 
  361.       {
  362.          switch (wParam) 
  363.          {
  364.            case IDD_CHANGE:            //* change links
  365.                BLOCK_BUSY(fTry);
  366.                if (ChangeLinks(hDlg,nLinks,hwndList,pLinks))
  367.                   DisplayUpdate(nLinks,hwndList,pLinks, FALSE);
  368.                return TRUE;
  369.  
  370.            case IDD_FREEZE:            //* cancel links
  371.                BLOCK_BUSY(fTry);
  372.                CancelLinks(hDlg,nLinks,hwndList,pLinks);
  373.                UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  374.                return TRUE;
  375.  
  376.            case IDD_UPDATE:            //* update links
  377.                BLOCK_BUSY(fTry);
  378.                DisplayUpdate(nLinks,hwndList,pLinks,TRUE);
  379.                UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  380.                return TRUE;
  381.  
  382.             case IDD_AUTO:
  383.             case IDD_MANUAL:           //* change link update options
  384.                BLOCK_BUSY(fTry);
  385.                if (!SendMessage(GetDlgItem(hDlg,wParam),BM_GETCHECK, 0, 0L))
  386.                {
  387.                   CheckRadioButton(hDlg, IDD_AUTO ,IDD_MANUAL ,wParam);
  388.                   ChangeUpdateOptions(hDlg,nLinks,hwndList,pLinks, 
  389.                      (wParam == IDD_AUTO ? oleupdate_always : oleupdate_oncall));
  390.                   UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  391.                }
  392.                return TRUE;
  393.  
  394.            case IDD_LINKNAME:          
  395.                if (HIWORD(lParam) == LBN_SELCHANGE)
  396.                   UpdateLinkButtons(hDlg,nLinks,hwndList,pLinks);
  397.                return TRUE;
  398.  
  399.             case IDCANCEL:
  400.                BLOCK_BUSY(fTry);
  401.                UndoObjects();
  402.                END_PROP_DLG(hDlg,pLinks);
  403.                return TRUE;  
  404.  
  405.             case IDOK:
  406.                BLOCK_BUSY(fTry);
  407.                DelUndoObjects(FALSE);
  408.                END_PROP_DLG(hDlg,pLinks);
  409.                return TRUE;  
  410.          }  
  411.       }
  412.    }   
  413.    return FALSE;
  414. }
  415.  
  416.  
  417. /****************************************************************************
  418.  * InitLinkDlg();
  419.  *
  420.  * Initialize the list box of links.
  421.  ***************************************************************************/
  422.  
  423. static BOOL InitLinkDlg (              //* ENTRY:
  424.    HWND           hDlg,                //* dialog box handle
  425.    int            *nLinks,             //* pointer to number of links
  426.    HWND           hwndList,            //* listbox handle
  427.    APPITEMPTR     **pLinks             //* list of window handles of links 
  428. ){                                     //* LOCAL
  429.    APPITEMPTR     pItem;               //* application item pointer
  430.    LPSTR          lpstrData = NULL;    //* pointer to link data
  431.    char           szFull[CBMESSAGEMAX * 4];//* list box entry string
  432.    char           pLinkData[OBJECT_LINK_MAX];//* holder of link data
  433.    BOOL           fSelect = FALSE;     //* item selected flag
  434.    HANDLE         hWork;               //* working memory handle
  435.    APPITEMPTR     pTop;                //* pointer to the top object
  436.  
  437.    if (!(*pLinks = (APPITEMPTR *)LocalLock(LocalAlloc(LHND,sizeof(APPITEMPTR)*10))))
  438.    {  
  439.       ErrorMessage(E_FAILED_TO_ALLOC); 
  440.       return NULL;
  441.    }   
  442.    *nLinks = 0;
  443.                                        //* set tabs
  444.    SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  445.                                        //* enumerate child windows
  446.    for (pTop = pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  447.    {
  448.       if (pItem->otObject == OT_LINK && pItem->fVisible) 
  449.       {
  450.          *(*pLinks + *nLinks) = pItem; 
  451.          if (!((*nLinks += 1)%10))
  452.          {                             //* add blocks of ten
  453.             hWork = LocalHandle((WORD)*pLinks);
  454.             LocalUnlock(hWork);
  455.             if (!(hWork = LocalReAlloc(hWork,(*nLinks+10)*sizeof(APPITEMPTR),NULL)))
  456.             {
  457.                ErrorMessage(E_FAILED_TO_ALLOC);
  458.                return FALSE;           //* ERROR return
  459.             }
  460.             *pLinks = (APPITEMPTR *)LocalLock(hWork);
  461.          }
  462.  
  463.          if (pTop == pItem)
  464.             fSelect = TRUE;
  465.  
  466.          if (!ObjGetData(pItem, pLinkData))
  467.             continue;
  468.                                        //* make listbox entry
  469.          MakeListBoxString(pLinkData, szFull, pItem->uoObject);
  470.                                        //* add listbox entry
  471.          SendMessage(hwndList, LB_ADDSTRING, 0, (LONG)(LPSTR)szFull);
  472.       }
  473.    }
  474.  
  475.    if (fSelect)
  476.       SendMessage(hwndList, LB_SETSEL, 1, 0L);
  477.    
  478.    SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  479.    UpdateWindow(hwndList);            
  480.  
  481.    return TRUE;                        //* SUCCESS return
  482.                                        
  483. }
  484.  
  485. /****************************************************************************
  486.  * MakeListBoxString()
  487.  *
  488.  * build an listbox entry string
  489.  ***************************************************************************/
  490.  
  491. static void MakeListBoxString(         //* ENTRY:
  492.    LPSTR          lpLinkData,          //* pointer to link data
  493.    LPSTR          lpBoxData,           //* return string
  494.    OLEOPT_UPDATE  oleopt_update        //* OLE update option
  495. ){                                     //* LOCAL:
  496.    char           szType[CBMESSAGEMAX];//* holds update option string
  497.    LPSTR          lpTemp;              //* working string pointer
  498.    int            i;                   //* index
  499.    
  500.                                        //* get classname
  501.    RegGetClassId(lpBoxData, lpLinkData);
  502.    lstrcat(lpBoxData, " - ");           //* ads tab
  503.       
  504.    while (*lpLinkData++);              //* skip to document name
  505.  
  506.    lpTemp = lpLinkData;
  507.    while (*lpTemp)                     //* copy document name;
  508.    {                                   //* strip drive an directory
  509.       if (*lpTemp == '\\' || *lpTemp == ':')
  510.          lpLinkData = lpTemp + 1;
  511.       lpTemp = AnsiNext(lpTemp);
  512.    }
  513.    lstrcat(lpBoxData, lpLinkData);
  514.    lstrcat(lpBoxData, " - ");
  515.  
  516.    while (*lpLinkData++);              //* copy item data
  517.    lstrcat(lpBoxData, lpLinkData);
  518.    lstrcat(lpBoxData, " - ");
  519.                                        //* add update option string
  520.    switch (oleopt_update)
  521.    {
  522.       case oleupdate_always: i = SZAUTO; break;
  523.       case oleupdate_oncall: i = SZMANUAL; break;
  524.       default: i = SZFROZEN;
  525.    }
  526.    LoadString(hInst, i, szType, CBMESSAGEMAX);
  527.    lstrcat(lpBoxData, szType);
  528.  
  529. }                                      //* SUCCESS return
  530.  
  531. /***************************************************************************
  532.  * UpdateLinkButtons()
  533.  *
  534.  * Keep link buttons active as appropriate.  This routine is called after
  535.  * a selection is made so the buttons reflect the selected items.
  536.  **************************************************************************/
  537.  
  538. static void UpdateLinkButtons(         //* ENTRY:
  539.    HWND           hDlg,                //* dialog box handle
  540.    int            nLinks,              //* number of links
  541.    HWND           hwndList,            //* listbox handle
  542.    APPITEMPTR     *pLinks              //* pointer to link's window handles
  543. ){                                     //* LOCAL:
  544.    ATOM           aCurName=0;          //* atom of current doc
  545.    BOOL           fChangeLink = TRUE;  //* enable/disable changelink button
  546.    int            iAuto,iManual,i;     //* count of manual and auto links
  547.    APPITEMPTR     pItem;               //* application item pointer
  548.    int            iStatic;
  549.  
  550.    iStatic = iAuto = iManual = 0;
  551.  
  552.    for (i = 0; i < nLinks; i++)        //* enum selected links    
  553.    {
  554.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  555.       {
  556.          pItem = *(pLinks+i);
  557.          if (pItem->otObject == OT_STATIC)
  558.             iStatic++;
  559.          else
  560.          {
  561.             switch(pItem->uoObject) 
  562.             {                          //* count number of manual and 
  563.                case oleupdate_always:  //* automatic links selected
  564.                   iAuto++;
  565.                   break;
  566.                case oleupdate_oncall:
  567.                   iManual++;
  568.                   break;
  569.             }
  570.                                        //* check if all selected links are
  571.             if (!aCurName)             //* linked to same file
  572.                aCurName = pItem->aLinkName;
  573.             else if (aCurName != pItem->aLinkName)
  574.                fChangeLink = FALSE;
  575.          }
  576.       }
  577.    }
  578.  
  579.    if (!(iAuto || iManual || iStatic)  //* if no links disable all buttons
  580.       || (!iAuto && !iManual && iStatic))
  581.    {
  582.       EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), FALSE );
  583.       EnableWindow(GetDlgItem(hDlg, IDD_CHANGE), FALSE );
  584.       EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), FALSE );
  585.       CheckDlgButton(hDlg, IDD_AUTO, FALSE);
  586.       EnableWindow(GetDlgItem(hDlg, IDD_AUTO),FALSE);
  587.       CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
  588.       EnableWindow(GetDlgItem(hDlg, IDD_MANUAL),FALSE);
  589.    }
  590.    else
  591.    { 
  592.       EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), TRUE );
  593.       EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), TRUE );
  594.  
  595.       if (iAuto && iManual || !(iAuto || iManual))
  596.       {                                //* Set update buttons 
  597.          CheckDlgButton(hDlg, IDD_AUTO, FALSE);
  598.          EnableWindow(GetDlgItem(hDlg, IDD_AUTO),FALSE);
  599.          CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
  600.          EnableWindow(GetDlgItem(hDlg, IDD_MANUAL),FALSE);
  601.       }
  602.       else 
  603.       {
  604.          EnableWindow(GetDlgItem(hDlg, IDD_MANUAL), TRUE);
  605.          EnableWindow(GetDlgItem(hDlg, IDD_AUTO), TRUE);
  606.          if (iAuto)
  607.          {  
  608.             CheckDlgButton(hDlg, IDD_AUTO, TRUE);
  609.             CheckDlgButton(hDlg, IDD_MANUAL, FALSE);
  610.          }
  611.          else
  612.          {
  613.             CheckDlgButton(hDlg, IDD_AUTO, FALSE);
  614.             CheckDlgButton(hDlg, IDD_MANUAL, TRUE);
  615.          }
  616.       }
  617.    } 
  618.  
  619.    EnableWindow(GetDlgItem(hDlg, IDD_CHANGE),fChangeLink && aCurName);
  620.  
  621. }
  622.  
  623. /****************************************************************************
  624.  * ChangeLinks()
  625.  *
  626.  * This routine changes the linked data if the user chooses a new file to
  627.  * replace the old document data portion of the linked date.  The routine
  628.  * does nothing if the user cancels.
  629.  *
  630.  * returns TRUE - if data changed FALSE if user cancel or err.
  631.  ***************************************************************************/
  632.  
  633. static BOOL ChangeLinks(               //* ENTRY:
  634.    HWND           hDlg,                //* dialog handle
  635.    int            nLinks,              //* number of links in listbox
  636.    HWND           hwndList,            //* listbox
  637.    APPITEMPTR     *pLinks              //* list of application link handles
  638. ){                                     //* LOCAL
  639.    int            i;                   //* general index
  640.    HANDLE         hWork;               //* work
  641.    APPITEMPTR     pItem;               //* application item
  642.    LPSTR          lpNewDoc = NULL;     //* new document
  643.    ATOM           aOldDoc;             //* atom of old doc. name
  644.    ATOM           aCurDoc = NULL;      //* atom of change-to doc. name
  645.    BOOL           fMessage = FALSE;    //* error message flag
  646.    LPSTR          lpLinkData;          //* pointer to link data
  647.    
  648.    lpLinkData = NULL;
  649.                                        //* This loop finds all selected links
  650.    for (i = 0; i < nLinks; i++)        //* and updates them
  651.    {
  652.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  653.       {
  654.          pItem = *(pLinks+i);
  655.          CHECK_IF_STATIC(pItem);
  656.  
  657.          pItem->lpLinkData = lpLinkData;
  658.          if (!ObjGetData(pItem,NULL))
  659.             continue;
  660.  
  661.          if (!lpNewDoc)
  662.          {
  663.             if (!(lpNewDoc = OfnGetNewLinkName(hDlg, pItem->lpLinkData)))
  664.               return FALSE;            //* ERROR jump
  665.             aOldDoc = pItem->aLinkName;
  666.             aCurDoc = AddAtom(lpNewDoc);
  667.             SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  668.          }
  669.  
  670.          ObjSaveUndo(pItem);  
  671.          ObjChangeLinkData(pItem,lpNewDoc);
  672.          pItem->aLinkName = aCurDoc;
  673.          lpLinkData = pItem->lpLinkData;
  674.  
  675.          CHANGE_LISTBOX_STRING(hwndList, i, pItem, pItem->lpLinkData);
  676.  
  677.          pItem->lpLinkData = NULL;
  678.       }
  679.    }                                   
  680.  
  681.    /*************************************************************************
  682.    * now deal with non-selected links and look for a match...
  683.    *************************************************************************/
  684.  
  685.                                        //* this loop finds non-selected links
  686.    for (i = 0; i < nLinks; i++)        //* and asks the user to update these?
  687.    {
  688.       if (!SendMessage(hwndList, LB_GETSEL, i, 0L))
  689.       {
  690.          pItem = *(pLinks+i);
  691.          if (pItem->otObject == OT_STATIC)
  692.             continue;
  693.          
  694.          if (!ObjGetData(pItem,NULL))
  695.             continue;
  696.  
  697.          if (pItem->aLinkName == aOldDoc)
  698.          {
  699.             if (!fMessage)
  700.             {
  701.                char szMessage[2*CBMESSAGEMAX+3*CBPATHMAX];
  702.                char szRename[2*CBMESSAGEMAX];
  703.                char szOldDoc[CBMESSAGEMAX];
  704.                LPSTR pOldDoc;
  705.             
  706.                GetAtomName(aOldDoc,szOldDoc,CBMESSAGEMAX);
  707.                pOldDoc =(LPSTR)UnqualifyPath(szOldDoc); 
  708.                LoadString(hInst, IDS_RENAME, szRename, 2*CBMESSAGEMAX);
  709.                wsprintf(
  710.                      szMessage,
  711.                      szRename,
  712.                      pOldDoc,
  713.                      (LPSTR)UnqualifyPath(szFileName),
  714.                      pOldDoc
  715.                );
  716.  
  717.                if (MessageBox(hDlg, szMessage, 
  718.                   szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDNO) 
  719.                   break;
  720.                fMessage = TRUE;
  721.             }
  722.  
  723.             ObjSaveUndo(pItem);  
  724.             ObjChangeLinkData(pItem,lpNewDoc);
  725.             CHANGE_LISTBOX_STRING(hwndList, i, pItem, pItem->lpLinkData);
  726.   
  727.             pItem->aLinkName = aCurDoc;
  728.          }
  729.       }
  730.    } 
  731.  
  732.    if(lpNewDoc)
  733.    {
  734.       hWork = (HANDLE)GlobalHandle(HIWORD(lpNewDoc));
  735.       GlobalUnlock(hWork);
  736.       GlobalFree(hWork);
  737.    }
  738.  
  739.    if (lpLinkData)
  740.       FreeLinkData(lpLinkData);
  741.  
  742.    SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  743.    InvalidateRect(hwndList,NULL,TRUE);
  744.    UpdateWindow(hwndList);
  745.  
  746.    WaitForAllObjects();
  747.  
  748.    if (aCurDoc)
  749.       DeleteAtom(aCurDoc);
  750.  
  751.    return(TRUE);
  752. }
  753.  
  754. /****************************************************************************
  755.  * DisplayUpdate()
  756.  *
  757.  * Get the most up to date rendering information and show it.  
  758.  ***************************************************************************/
  759.  
  760. static void DisplayUpdate(             //* ENTRY:
  761.    int            nLinks,              //* number of links in listbox
  762.    HWND           hwndList,            //* listbox
  763.    APPITEMPTR     *pLinks,             //* list of application link handles
  764.    BOOL           fSaveUndo            //* save undo objects
  765. ){                                     //* LOCAL:
  766.    int            i;                   //* index
  767.    APPITEMPTR     pItem;               //* temporary item pointer
  768.  
  769.  
  770.    for (i = 0; i < nLinks; i++) 
  771.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  772.       {
  773.          pItem = *(pLinks+i);
  774.          CHECK_IF_STATIC(pItem);
  775.          if (fSaveUndo)
  776.             ObjSaveUndo(pItem);
  777.          Error(OleUpdate(pItem->lpObject));
  778.       }
  779.  
  780.    WaitForAllObjects();
  781.  
  782. }
  783.  
  784. /****************************************************************************
  785.  * UndoObjects()
  786.  *
  787.  * Bring objects back to their original state.
  788.  ***************************************************************************/
  789.  
  790. static void UndoObjects()
  791. {                                     
  792.    APPITEMPTR     pItem;               //* application item pointer
  793.                                        //* enum objects
  794.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  795.       if (pItem->lpObjectUndo) 
  796.          ObjUndo(pItem);
  797.    
  798.    WaitForAllObjects();
  799.  
  800. }
  801.  
  802.  
  803. /****************************************************************************
  804.  * DelUndoObjects()
  805.  *
  806.  * remove all objects created for undo operation.
  807.  ***************************************************************************/
  808.  
  809. static void DelUndoObjects(            //* ENTRY:
  810.    BOOL           fPrompt              //* prompt user?
  811. ){                                     //* LOCAL:
  812.    APPITEMPTR     pItem;               //* application item pointer
  813.    BOOL           fPrompted = FALSE;   //* prompted user?
  814.  
  815.    for (pItem = GetTopItem(); pItem; pItem = GetNextItem(pItem))
  816.    {
  817.       if (pItem->lpObjectUndo) 
  818.       {
  819.          if (fPrompt && !fPrompted)    //* prompt user in activation case
  820.          {
  821.             char szPrompt[CBMESSAGEMAX];
  822.  
  823.             LoadString(hInst, IDS_SAVE_CHANGES, szPrompt, CBMESSAGEMAX);
  824.  
  825.             if (MessageBox(hwndFrame, szPrompt, 
  826.                   szAppName, MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
  827.             {
  828.                UndoObjects(); 
  829.                return;                 //* user canceled operation
  830.             }
  831.             fPrompted = TRUE;
  832.          }
  833.         ObjDelUndo(pItem);             //* delete udo object
  834.       }
  835.    }
  836.  
  837.    WaitForAllObjects();
  838.  
  839. }                                      //* SUCCESS return
  840.  
  841. /****************************************************************************
  842.  * CancelLinks()
  843.  ***************************************************************************/
  844.  
  845. static void CancelLinks(               //* ENTRY:
  846.    HWND           hDlg,                //* calling dialog
  847.    int            nLinks,              //* number of links in listbox
  848.    HWND           hwndList,            //* listbox
  849.    APPITEMPTR     *pLinks              //* list of application link handles
  850. ){                                     //* LOCAL:
  851.    APPITEMPTR     pItem;               //* application item pointer
  852.    int            i;                   //* index
  853.    char           pLinkData[OBJECT_LINK_MAX];//* holder of link data
  854.  
  855.    SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  856.    for (i = 0; i < nLinks; i++) 
  857.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  858.       {
  859.          pItem = *(pLinks+i);
  860.          CHECK_IF_STATIC(pItem);
  861.          ObjGetData(pItem,pLinkData);
  862.          ObjSaveUndo(pItem);
  863.          ObjFreeze(pItem);
  864.  
  865.          CHANGE_LISTBOX_STRING(hwndList, i, pItem, pLinkData);
  866.       }
  867.  
  868.    SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  869.    InvalidateRect(hwndList,NULL,TRUE);
  870.    UpdateWindow(hwndList);
  871.  
  872. }
  873.          
  874.  
  875. /****************************************************************************
  876.  * ChangeUpdateOptions()
  877.  *
  878.  * Change the update options for all selected objects.
  879.  ***************************************************************************/
  880.  
  881. static void ChangeUpdateOptions(       //* ENTRY:
  882.    HWND           hDlg,                //* calling dialog
  883.    int            nLinks,              //* number of links in listbox
  884.    HWND           hwndList,            //* listbox
  885.    APPITEMPTR     *pLinks,             //* list of application link handles
  886.    OLEOPT_UPDATE  lUpdate              //* update option
  887. ){                                     //* LOCAL:
  888.    APPITEMPTR     pItem;               //* application item
  889.    int            i;                   //* index
  890.    char           pLinkData[OBJECT_LINK_MAX];
  891.  
  892.    SendMessage(hwndList,WM_SETREDRAW,FALSE,0L);
  893.    
  894.    for (i = 0; i < nLinks; i++)        //* enum selected objects
  895.    {
  896.       if (SendMessage(hwndList, LB_GETSEL, i, 0L))
  897.       {
  898.          pItem = *(pLinks+i);
  899.          CHECK_IF_STATIC(pItem);
  900.          ObjGetData(pItem,pLinkData);
  901.          ObjSaveUndo(pItem);
  902.          if (Error(OleSetLinkUpdateOptions(pItem->lpObject,lUpdate)))
  903.             continue;
  904.          pItem->uoObject = lUpdate;
  905.  
  906.          CHANGE_LISTBOX_STRING(hwndList, i, pItem, pLinkData);
  907.       }
  908.    }
  909.  
  910.    SendMessage(hwndList,WM_SETREDRAW,TRUE,0L);
  911.    InvalidateRect(hwndList,NULL,TRUE);
  912.    UpdateWindow(hwndList);
  913.    WaitForAllObjects();
  914.  
  915. }
  916. /****************************************************************************
  917.  * InvalidLink()
  918.  *
  919.  * Deal with letting the user know that the program has inadvertently come
  920.  * across an invalid link.
  921.  * 
  922.  * Global fPropBoxActive - flag to determine whether or not the link dialog 
  923.  *                         box is active.  If it is not active we give the
  924.  *                         user an opportunity to enter the links property
  925.  *                         dialog directly from here.
  926.  ***************************************************************************/
  927.  
  928. void FAR InvalidLink()
  929. {   
  930.  
  931.    if (!hwndProp)
  932.    {
  933.       FARPROC lpfnInvalidLink=NULL;
  934.  
  935.       lpfnInvalidLink = MakeProcInstance(fnInvalidLink, hInst);
  936.       DialogBox(hInst, "InvalidLink", hwndFrame, lpfnInvalidLink);
  937.       FreeProcInstance(lpfnInvalidLink);
  938.    }
  939.    else
  940.       ErrorMessage(E_FAILED_TO_CONNECT);
  941.  
  942. }
  943.  
  944. /****************************************************************************
  945.  *  fnABout()
  946.  *
  947.  *  About box dialog box procedure.
  948.  ***************************************************************************/
  949.  
  950. BOOL FAR PASCAL fnInvalidLink(        //* ENTRY: 
  951.    HWND           hDlg,                //* standard windows dialog box
  952.    unsigned       message, 
  953.    WORD           wParam, 
  954.    LONG           lParam 
  955. ){
  956.  
  957.    switch (message) 
  958.    {
  959.       case WM_INITDIALOG:
  960.          return (TRUE);
  961.  
  962.       case WM_COMMAND:
  963.          if (wParam == IDD_CHANGE)
  964.             LinkProperties();   
  965.          EndDialog(hDlg, TRUE);
  966.          return (TRUE);
  967.     }
  968.     return (FALSE);
  969.  
  970. }
  971.  
  972. /****************************************************************************
  973.  *  AboutBox()
  974.  *
  975.  *  Show the About Box dialog.
  976.  ***************************************************************************/
  977.  
  978. void FAR AboutBox()            
  979. {     
  980.    FARPROC lpfnProcAbout=NULL;
  981.  
  982.    lpfnProcAbout = MakeProcInstance(fnAbout, hInst);
  983.    DialogBox(hInst, "AboutBox", hwndFrame, lpfnProcAbout);
  984.    FreeProcInstance(lpfnProcAbout);
  985.  
  986. }
  987.  
  988. /****************************************************************************
  989.  *  fnABout()
  990.  *
  991.  *  About box dialog box procedure.
  992.  ***************************************************************************/
  993.  
  994. BOOL FAR PASCAL fnAbout(               //* ENTRY: 
  995.    HWND           hDlg,                //* standard windows dialog box
  996.    unsigned       message, 
  997.    WORD           wParam, 
  998.    LONG           lParam 
  999. ){
  1000.  
  1001.    switch (message) 
  1002.    {
  1003.       case WM_INITDIALOG:
  1004.          return (TRUE);
  1005.  
  1006.       case WM_COMMAND:
  1007.          if (wParam == IDOK || wParam == IDCANCEL) 
  1008.          {
  1009.             EndDialog(hDlg, TRUE);
  1010.             return (TRUE);
  1011.          }
  1012.          break;
  1013.     }
  1014.     return (FALSE);
  1015.  
  1016. }
  1017.  
  1018.  
  1019.  
  1020. /***************************************************************************
  1021.  * RetryMessage()
  1022.  *
  1023.  * give the user the chance to abort when a server is in retry case.
  1024.  *
  1025.  * Returns BOOL - TRUE if user chooses to cancel
  1026.  **************************************************************************/
  1027.  
  1028. void FAR RetryMessage (                //* ENTRY:
  1029.    APPITEMPTR     paItem,              //* application item pointer
  1030.    LONG           lParam
  1031. ){ 
  1032.    RETRYPTR    pRetry;
  1033.    LONG          objectType;
  1034.    HANDLE       hData;
  1035.    static char szServerName[KEYNAMESIZE];
  1036.    HWND        hwnd;                   //* window handle
  1037.    FARPROC     lpfn;                   //* pointer to far
  1038.  
  1039.    if (IsWindow(hwndProp))
  1040.       hwnd = hwndProp;
  1041.    else if (IsWindow(hwndFrame))
  1042.       hwnd = hwndFrame; 
  1043.    else
  1044.       return;                          //* should not happen
  1045.                                        //* get the busy servers name
  1046.    lstrcpy(szServerName, "server application");
  1047.  
  1048.    if (paItem)
  1049.    {
  1050.       if (!paItem->aServer)
  1051.       {
  1052.          OleQueryType(paItem->lpObject, &objectType );
  1053.          if (OLE_OK == OleGetData(paItem->lpObject, (objectType == OT_LINK ? vcfLink : vcfOwnerLink), &hData ))
  1054.          {
  1055.             RegGetClassId(szServerName, GlobalLock(hData));
  1056.             paItem->aServer = AddAtom(szServerName);
  1057.             GlobalUnlock( hData );
  1058.          }  
  1059.       }
  1060.       else
  1061.          GetAtomName(paItem->aServer,szServerName,KEYNAMESIZE);
  1062.          
  1063.    }
  1064.  
  1065.    hData = LocalAlloc(LHND,sizeof(RETRYSTRUCT));
  1066.    if(!(pRetry = (RETRYPTR)LocalLock(hData)))
  1067.      return;
  1068.  
  1069.    pRetry->lpserver = (LPSTR)szServerName;
  1070.    pRetry->bCancel  = (BOOL)(lParam & RD_CANCEL);
  1071.    pRetry->paItem   = paItem;
  1072.  
  1073.    lpfn = MakeProcInstance(fnRetry,hInst);
  1074.    DialogBoxParam(hInst, "RetryBox", hwnd, lpfn, (LONG)pRetry );
  1075.    FreeProcInstance(lpfn);
  1076.  
  1077.    LocalUnlock(hData);
  1078.    LocalFree(hData);
  1079.  
  1080.    hRetry = NULL;
  1081.  
  1082. }
  1083.  
  1084. /****************************************************************************
  1085.  *  fnRetry()
  1086.  *
  1087.  * Retry message box nothing to tricky; however, when a server becomes 
  1088.  * unbusy a message is posted to automatically get rid of this dialog.
  1089.  * I send a no.
  1090.  ***************************************************************************/
  1091.  
  1092. BOOL FAR PASCAL fnRetry(               //* ENTRY
  1093.    HWND hDlg,                          //* standard dialog entry
  1094.    WORD message, 
  1095.    WORD wParam, 
  1096.    DWORD lParam
  1097. ){
  1098.    static RETRYPTR   pRetry;
  1099.  
  1100.    switch (message) 
  1101.    {
  1102.       case WM_COMMAND:
  1103.          switch (wParam) 
  1104.          {
  1105.                case IDD_SWITCH:
  1106.                      DefWindowProc( hDlg, WM_SYSCOMMAND, SC_TASKLIST, NULL);
  1107.                   break;
  1108.  
  1109.                case IDCANCEL:
  1110.                   if (pRetry->paItem)
  1111.                      pRetry->paItem->fRetry = FALSE;
  1112.                   EndDialog(hDlg, TRUE);
  1113.                   return TRUE;
  1114.  
  1115.                default:
  1116.                    break;
  1117.          }
  1118.          break;
  1119.  
  1120.       case WM_INITDIALOG:
  1121.       {
  1122.           char       szBuffer[CBMESSAGEMAX];
  1123.           char       szText[2*CBMESSAGEMAX];
  1124.           
  1125.           pRetry = (RETRYPTR)lParam;
  1126.           hRetry = hDlg;
  1127.        
  1128.           LoadString(hInst, IDS_RETRY_TEXT1, szBuffer, CBMESSAGEMAX);
  1129.           wsprintf(szText, szBuffer, pRetry->lpserver);
  1130.           SetWindowText (GetDlgItem(hDlg, IDD_RETRY_TEXT1), szText);
  1131.  
  1132.           LoadString(hInst, IDS_RETRY_TEXT2, szBuffer, CBMESSAGEMAX);
  1133.           wsprintf(szText, szBuffer, pRetry->lpserver);
  1134.           SetWindowText (GetDlgItem(hDlg, IDD_RETRY_TEXT2), szText);
  1135.        
  1136.           EnableWindow (GetDlgItem(hDlg, IDCANCEL), pRetry->bCancel);
  1137.  
  1138.           return TRUE; 
  1139.       }
  1140.        
  1141.       default:
  1142.            break;
  1143.    }
  1144.  
  1145.    return FALSE;
  1146. }
  1147.